/*******************************************************************************
 * Copyright 2011 @ Kapil Viren Ahuja
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package com.kapil.framework.reader;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import com.kapil.framework.logger.ILogger;
import com.kapil.framework.logger.LogFactory;


/**
 * <p>
 * This implementation of the {@link IMessageReader} locates the messages from a
 * resource bundle located in the application classpath. This implementation, has the capability
 * to read messages from multiple data sources.
 * 
 * In addition, this implementation, provides the capabilities to read locale based messages.
 * </p>
 * 
 * <strong>To use this implementation:</strong>
 * <pre>
 * // Initialize the message reader for the resourceBundle, reading the messages from a bundle names "userMessages"
 * IMessageReader messageReader = MessageReaderFactory.getInstance().getReader(resourceBundles, "userMessages");
 * 
 * // Get a message based on a key for the current locale.
 * String message = messageReader.getMessage("someKey");
 * // Get a message based on a key for the specific locale.
 * String message = messageReader.getMessage("someKey", Locale.UK_en);
 * </pre>
 */
public final class ResourceBundleMessageReader extends MessageReader
{
    
    /** The logger. */
    private static final ILogger logger = LogFactory.getInstance().getLogger(ResourceBundleMessageReader.class);

    
    /**
     * Only Constructor needs a list of data sources to instantiate the reader.
     * 
     * @param dataSources a {@link ArrayList} containing data sources that need to be searched for keys
     * 
     */
    public ResourceBundleMessageReader(List<String> dataSources)
    {
        super(dataSources);
    }
    

    /**
     * Gets the message from the resource bundle.
     * 
     * @param key {@link String} containing key which needs to be read from the bundle.
     * 
     * @return {@link String} containing the message for the key.
     * 
     */
    public String getMessage(final String key)
    {
        return getMessage(key, Locale.getDefault());
    }

    /**
     * Gets the message from the resource bundle for a specific locale.
     * 
     * @param key {@link String} containing key which needs to be read from the bundle.
     * @param locale {@link Locale} for which the message needs to read from.
     * 
     * @return {@link String} containing the message for the key. If not key is found in any of the data sources,
     * we return a <code>blank String</code>.
     * 
     */
    public String getMessage(final String key, final Locale locale)
    {
        if (super.getDataSources() == null)
        {
            throw new RuntimeException("No datasources found for the Message Reader.");
        }

        String message = "";
        int size = super.getDataSources().size();
        for (int index = 0; index < size; ++index)
        {
            try
            {
                logger.debug("Reading key [" + key + "] from datasource [" + super.getDataSources().get(index) + "]");
                message = ResourceBundle.getBundle(super.getDataSources().get(index), locale).getString(key);
            }
            catch (MissingResourceException mrex)
            {
                // We do not want to throw an exception in case no key was found so that the search can continue for other data sources.
                // This exception has been ignored purposefully.
                logger.info("No key was found for ## in the reader.", new String[] { key });
            }
        }

        return message;
    }
}
